package org.smile.validate;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;

import org.smile.annotation.AnnotationUtils;
import org.smile.collection.ArrayUtils;
import org.smile.collection.CollectionUtils;
import org.smile.commons.SmileRunException;
import org.smile.commons.Strings;
import org.smile.plugin.MethodHashKey;
import org.smile.reflect.MethodParamNameUtils;
import org.smile.util.StringUtils;
import org.smile.validate.rule.FiledValidateRule;

public class ValidateElementUtils {
	/**
	 * 初始始化一个类的方法 的注解验证配置信息
	 * @param method 要验证的方法
	 * @return
	 */
	public static ValidateElement checkAnnotationValidate(Method method){
		ValidateElement validateElement=null;
		try {
			//主注解
			Validate validate = AnnotationUtils.getAnnotation(method,Validate.class);
			String prefix=Strings.BLANK;
			if (validate != null) {
				prefix=validate.prefix();
				Field[] fs = validate.fields();
				validateElement= newValidateElement(prefix,fs);
			}
			//其它子注解解析
			Set<Field> fields = AnnotationUtils.getRepeatableAnnotations(method,Field.class,Validate.class);
			if(fields.size()>0){
				if(validateElement==null) {
					validateElement= newValidateElement(Strings.BLANK, fields);
				}else{
					Collection<Rule> rules= new LinkedList<>();
					convert(prefix,fields,rules);
					validateElement.join(rules);
				}
			}
			//参数中的验证注解
			List<Rule> parameterRules = getRuleFromParameters(method);
			if(parameterRules.size()>0){
				if(validateElement==null) {
					validateElement=new ValidateElement(parameterRules);
				}else{
					validateElement.join(parameterRules);
				}
			}
			//参数中的注解
		} catch (Exception e) {
			throw new SmileRunException("初始化注解验证配置信息出错"+method.getDeclaringClass()+" method "+method, e);
		}
		return validateElement;
	}

	/**
	 * 从参数中获取校验规则
	 * @return
	 */

	public static List<Rule> getRuleFromParameters(Method method){
		//参数注解parameterAnnos
		Annotation[][] parameterAnns=method.getParameterAnnotations();
		List<Rule> ruleList = new LinkedList<>();
		if(ArrayUtils.notEmpty(parameterAnns)){
			int index=0;
			String[] names = MethodParamNameUtils.getParamNames(method);
			for(Annotation[] anns:parameterAnns){
				if(anns.length>0) {
					Set<Field> oneParamAnns = AnnotationUtils.getAnnotations(anns, Field.class);
					if (CollectionUtils.notEmpty(oneParamAnns)) {
						convertParamField(names[index], oneParamAnns, ruleList);
					}
				}
				index++;
			}
		}
		return ruleList;
	}

	private static void convertParamField(String parameter, Iterable<Field> fields,Collection<Rule> rules){
		for(Field f:fields){
			FiledValidateRule rule=new FiledValidateRule(f);
			rule.setProperty(parameter);
			rules.add(rule);
		}
	}

	/**
	 * 从一个类的字段中获取校验规则
	 * @param clazz
	 * @return
	 */
	public static Rule[] getRuleFromFields(Class clazz){
		return null;
	}

	/**
	 * 从注解验证初妈化一个验证元素
	 * @param fs
	 * @return
	 */
	public static ValidateElement newValidateElement(String prefix,Field[] fs){
		Collection<Rule> rules=new LinkedList<>();
		return newValidateElement(prefix, Arrays.asList(fs),rules);
	}

	/**
	 * 从注解验证初妈化一个验证元素
	 * @param fs
	 * @return
	 */
	public static ValidateElement newValidateElement(String prefix, Collection<Field> fs){
		Collection<Rule> rules=new LinkedList<>();
		return newValidateElement(prefix,fs,rules);
	}

	private static ValidateElement newValidateElement(String prefix, Iterable<Field> fields, Collection<Rule> rules){
		convert(prefix,fields,rules);
		return new ValidateElement(rules);
	}

	private static void convert(String prefix, Iterable<Field> fields,Collection<Rule> rules){
		for(Field f:fields){
			if(StringUtils.isEmpty(prefix)) {
				rules.add(new FiledValidateRule(f));
			}else{
				rules.add(new FiledValidateRule(prefix, f));
			}
		}
	}
}
